package com.yhn.init.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yhn.init.common.DeleteRequest;
import com.yhn.init.common.ErrorCode;
import com.yhn.init.exception.BusinessException;
import com.yhn.init.exception.ThrowUtils;
import com.yhn.init.mapper.InboundItemsMapper;
import com.yhn.init.mapper.PurchaseMapper;
import com.yhn.init.model.dto.inboundItems.*;
import com.yhn.init.model.entity.InboundItems;
import com.yhn.init.model.entity.Purchase;
import com.yhn.init.model.enums.InboundItemsStatusEnum;
import com.yhn.init.model.vo.InboundItemsVO;
import com.yhn.init.service.InboundItemsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author yhnyhn123
 */
@Slf4j
@Service("inboundItemsService")
public class InboundItemsServiceImpl extends ServiceImpl<InboundItemsMapper, InboundItems> implements InboundItemsService {

    @Resource
    private PurchaseMapper purchaseMapper;

    @Override
    public Page<InboundItemsVO> queryPage(InboundItemsQueryRequest inboundItemsQueryRequest) {
        if (inboundItemsQueryRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        long current = inboundItemsQueryRequest.getCurrent();
        long size = inboundItemsQueryRequest.getPageSize();
        // 限制爬虫
        ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);
        Page<InboundItems> inboundItemsPage = this.page(new Page<>(current, size),
                this.getQueryWrapper(inboundItemsQueryRequest));
        Page<InboundItemsVO> inboundItemsVOPage = new Page<>(current, size, inboundItemsPage.getTotal());
        List<InboundItemsVO> inboundItemsVO = this.getInboundItemsVO(inboundItemsPage.getRecords());
        inboundItemsVOPage.setRecords(inboundItemsVO);
        return inboundItemsVOPage;
    }


    @Override
    public QueryWrapper<InboundItems> getQueryWrapper(InboundItemsQueryRequest inboundItemsQueryRequest) {
        QueryWrapper<InboundItems> queryWrapper = new QueryWrapper<>();
        // 如果请求对象为空，直接返回一个空的查询包装器
        if (inboundItemsQueryRequest == null) {
            return queryWrapper;
        }
        // 从请求对象中获取各项查询条件
        Long id = inboundItemsQueryRequest.getId();
        queryWrapper.eq(id != null && id > 0, "id", id);
        return queryWrapper;
    }

    /**
     * 获取脱敏对象集合
     *
     * @param inboundItemsList 查询请求
     * @return 脱敏对象集合
     */
    @Override
    public List<InboundItemsVO> getInboundItemsVO(List<InboundItems> inboundItemsList) {
        if (CollUtil.isEmpty(inboundItemsList)) {
            return new ArrayList<>();
        }
        return inboundItemsList.stream().map(this::getInboundItemsVO).collect(Collectors.toList());
    }


    /**
     * 将对象转化为脱敏对象
     *
     * @param inboundItems 原对象
     * @return 脱敏对象
     */
    @Override
    public InboundItemsVO getInboundItemsVO(InboundItems inboundItems) {
        if (inboundItems == null) {
            return null;
        }
        InboundItemsVO inboundItemsVO = new InboundItemsVO();
        BeanUtils.copyProperties(inboundItems, inboundItemsVO);
        return inboundItemsVO;
    }

    /**
     * 根据ID获取信息
     *
     * @param id id
     * @return 实体信息
     */
    @Override
    public InboundItemsVO getInfoById(Long id) {
        InboundItems inboundItems = this.getById(id);
        if (inboundItems == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "没有对应的信息");
        }
        return getInboundItemsVO(inboundItems);
    }

    /**
     * 保存信息
     *
     * @param inboundItemsAddRequest 添加请求
     * @return 新生成的ID
     */
    @Override
    @Transactional
    public Long saveInboundItems(InboundItemsAddRequest inboundItemsAddRequest) {
        if (inboundItemsAddRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        InboundItems inboundItems = new InboundItems();
        Purchase purchase = purchaseMapper.selectById(inboundItemsAddRequest.getPurchaseId());
        ThrowUtils.throwIf(purchase == null, ErrorCode.NOT_FOUND_ERROR);

        BeanUtils.copyProperties(inboundItemsAddRequest, inboundItems);
        boolean result = this.save(inboundItems);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return inboundItems.getId();
    }


    /**
     * 修改信息
     *
     * @param inboundItemsUpdateRequest 修改请求
     * @return 是否修改成功
     */
    @Override
    @Transactional
    public Boolean updateInboundItems(InboundItemsUpdateRequest inboundItemsUpdateRequest) {
        if (inboundItemsUpdateRequest == null || inboundItemsUpdateRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        InboundItems inboundItems = new InboundItems();
        BeanUtils.copyProperties(inboundItemsUpdateRequest, inboundItems);
        long id = inboundItemsUpdateRequest.getId();
        // 判断是否存在
        InboundItems oldInboundItems = this.getById(id);
        ThrowUtils.throwIf(oldInboundItems == null, ErrorCode.NOT_FOUND_ERROR);
        boolean result = this.updateById(inboundItems);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return result;
    }

    /**
     * 删除信息
     *
     * @param deleteRequest 删除请求
     * @return 是否修改成功
     */
    @Override
    public Boolean deleteById(DeleteRequest deleteRequest) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        long id = deleteRequest.getId();
        // 判断是否存在
        boolean b = this.removeById(id);
        ThrowUtils.throwIf(!b, ErrorCode.NOT_FOUND_ERROR);
        return b;
    }


    /**
     * 批量删除
     *
     * @param ids 批量删除的IDS
     * @return 是否删除成功
     */
    @Override
    @Transactional
    public Boolean deleteBatchByIds(Long[] ids) {
        if (ids == null || ids.length == 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean b = this.removeByIds(Arrays.asList(ids));
        ThrowUtils.throwIf(!b, ErrorCode.NOT_FOUND_ERROR);
        return b;
    }

    /**
     * 财务确认入库
     *
     * @param financeConfirmRequest 财务确认请求
     * @return 是否通过
     */
    @Override
    public Boolean confirmByFinance(FinanceConfirmRequest financeConfirmRequest) {
        if (financeConfirmRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        InboundItems inboundItems = this.getById(financeConfirmRequest.getInboundItemsId());
        if (inboundItems == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        if (!inboundItems.getStatus().equals(InboundItemsStatusEnum.CREATED.getValue())) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        inboundItems.setStatus(financeConfirmRequest.getIsApproval() ?
                InboundItemsStatusEnum.CONFIRM.getValue() : InboundItemsStatusEnum.REJECTED.getValue());
        return financeConfirmRequest.getIsApproval();
    }

    /**
     * 经理确认入库
     *
     * @param managerConfirmRequest 经理确认请求
     * @return 是否通过
     */
    @Override
    @Transactional
    public Boolean confirmByManager(ManagerConfirmRequest managerConfirmRequest) {
        if (managerConfirmRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        InboundItems inboundItems = this.getById(managerConfirmRequest.getInboundItemsId());
        if (inboundItems == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        if (!inboundItems.getStatus().equals(InboundItemsStatusEnum.CONFIRM.getValue())) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        inboundItems.setStatus(managerConfirmRequest.getIsApproval() ?
                InboundItemsStatusEnum.APPROVED.getValue() : InboundItemsStatusEnum.REJECTED.getValue());
        return managerConfirmRequest.getIsApproval();
    }


}
